package com.eastfair.imaster.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.code.ExceptionCode;
import com.eastfair.imaster.dao.SpeakerListDetailsMapper;
import com.eastfair.imaster.dto.SpeakerListDetailsDTO;
import com.eastfair.imaster.dto.SpeakerListDetailsPageQuery;
import com.eastfair.imaster.entity.SpeakerListDetails;
import com.eastfair.imaster.mydao.MySpeakerListDetailsMapper;
import com.eastfair.imaster.service.SpeakerListDetailsService;
import com.eastfair.imaster.service.SpeakerListService;
import com.eastfair.imaster.vo.SpeakerListDetailsVO;
import com.eastfair.imaster.vo.SpeakerListVO;
import com.eastfair.projectcore.api.ProjectCoreServiceFeign;
import com.eastfair.core.snowflake.DefaultUidGenerator;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 业务实现类
 * 嘉宾列表详情
 * </p>
 *
 * @author zjn
 * @date 2021-09-02
 */
@Slf4j
@Service
@DS("#thread.tenant")
public class SpeakerListDetailsServiceImpl extends SuperServiceImpl<SpeakerListDetailsMapper, SpeakerListDetails> implements SpeakerListDetailsService {

    @Autowired
    ProjectCoreServiceFeign projectCoreServiceFeign;
    @Autowired
    private SpeakerListService speakerListService;
    @Autowired
    private MySpeakerListDetailsMapper mySpeakerListDetailsMapper;


    /**************sharding 分库分表操作 *****************/
    @Override
    public boolean updateByIdOfShard(SpeakerListDetails entity) {
        UpdateWrapper<SpeakerListDetails> updateWrapper = new UpdateWrapper<>();
        //可将指定字段更新为null
        updateWrapper.lambda().eq(SpeakerListDetails::getProjectId, entity.getProjectId()).eq(SpeakerListDetails::getId, entity.getId());
        entity.setProjectId(null);
        return SqlHelper.retBool(this.getBaseMapper().update(entity, updateWrapper));
    }

    /**
     * 处理新增相关处理
     *
     * @param model 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerSave(SpeakerListDetails model) {
        //雪花ID
        model.setId(DefaultUidGenerator.getUidOfProjectId(ContextUtil.getProjectId()));
        model.setProjectId(ContextUtil.getProjectId());
        return R.successDef();
    }

    @Override
    public Boolean deleteBySpeakerListId(Long speakerListId) {
        if (speakerListId == null) {
            throw new RuntimeException("error params, speakerListId is null");
        }
        UpdateWrapper<SpeakerListDetails> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(SpeakerListDetails::getProjectId, ContextUtil.getProjectId()).eq(SpeakerListDetails::getSpeakerListId, speakerListId)
                .set(SpeakerListDetails::getIsDeleted, BusinessConstant.ENABLE_YES);
        return update(updateWrapper);
    }

    @Override
    @GlobalTransactional(name = "addSpeakerListDetailsList", rollbackFor = Exception.class)
    public R<Boolean> addSpeakerListDetailsList(List<SpeakerListDetailsDTO> speakerListDetailsDTOList) {
        if (Objects.isNull(speakerListDetailsDTOList) || speakerListDetailsDTOList.size() < 1) {
            return R.fail(ExceptionCode.ERROR_NULL_PARAMS);
        }

        // 清除老列表的嘉宾
        UpdateWrapper<SpeakerListDetails> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(SpeakerListDetails::getProjectId, ContextUtil.getProjectId())
                .eq(SpeakerListDetails::getSpeakerListId, speakerListDetailsDTOList.get(0).getSpeakerListId())
                .set(SpeakerListDetails::getIsDeleted, BusinessConstant.DELETE_YES);
        update(updateWrapper);

        // 批量获取雪花id
        List<Long> ids = DefaultUidGenerator.getBatUidOfProjectId(ContextUtil.getProjectId(), speakerListDetailsDTOList.size());
        if (ids == null || ids.isEmpty()) {
            throw new RuntimeException("System exception, generate snowflake id error");
        }

        List<SpeakerListDetails> speakerListDetailsList = new ArrayList<>(speakerListDetailsDTOList.size());
        for (int i = 0; i < speakerListDetailsDTOList.size(); i++) {
            SpeakerListDetails speakerListDetails = SpeakerListDetails.builder().id(ids.get(i))
                    .projectId(ContextUtil.getProjectId()).sequence(speakerListDetailsDTOList.get(i).getSequence())
                    .speakerId(speakerListDetailsDTOList.get(i).getSpeakerId())
                    .speakerListId(speakerListDetailsDTOList.get(i).getSpeakerListId()).build();
            speakerListDetailsList.add(speakerListDetails);
        }

        return R.success(saveBatch(speakerListDetailsList));
    }

    @Override
    public R<Boolean> deleteSpeakerListDetails(Long id) {
        SpeakerListDetails speakerListDetails = SpeakerListDetails.builder().id(id).projectId(ContextUtil.getProjectId())
                .isDeleted(BusinessConstant.DELETE_YES).build();
        return R.success(updateByIdOfShard(speakerListDetails));
    }

    @Override
    public R<Page<SpeakerListDetailsVO>> queryPageDetails(PageParams<SpeakerListDetailsPageQuery> params) {
        SpeakerListDetailsPageQuery model = params.getModel();
        // 获取该列表排序方式
        if (Objects.isNull(model.getSpeakerListId())) {
            return R.fail(ExceptionCode.ERROR_NULL_PARAMS);
        }

        SpeakerListVO speakerListVO = speakerListService.queryById(model.getSpeakerListId());
        if (Objects.isNull(speakerListVO)) {
            return R.fail(ExceptionCode.ERROR_NULL_ID);
        }
        model.setSortOrderType(speakerListVO.getSortOrderType());
        model.setProjectId(ContextUtil.getProjectId());
        return R.success(mySpeakerListDetailsMapper.getPageBySpeakerListId(params.buildPage(), model));
    }

    @Override
    public R<List<SpeakerListDetailsVO>> queryListDetails(SpeakerListDetailsDTO speakerListDetailsDTO) {
        if (Objects.isNull(speakerListDetailsDTO) || Objects.isNull(speakerListDetailsDTO.getSpeakerListId())) {
            return R.fail(ExceptionCode.ERROR_NULL_PARAMS);
        }

        // 获取该列表排序方式
        SpeakerListVO speakerListVO = speakerListService.queryById(speakerListDetailsDTO.getSpeakerListId());
        if (Objects.isNull(speakerListVO)) {
            return R.fail(ExceptionCode.ERROR_NULL_ID);
        }
        speakerListDetailsDTO.setSortOrderType(speakerListVO.getSortOrderType());
        speakerListDetailsDTO.setProjectId(ContextUtil.getProjectId());
        return R.success(mySpeakerListDetailsMapper.getListBySpeakerListId(speakerListDetailsDTO));
    }
}